package com.wind.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *      进程工具类
 * </p>
 * @author wind
 * @date    2024-12-10 9:25
 * @version v1.0
 */
public class ProcessUtil {

    private ProcessUtil(){

    }


    /**
     * 执行命令
     * cmd /c dir 是执行完dir命令后关闭命令窗口。
     * cmd /k dir 是执行完dir命令后不关闭命令窗口。
     * cmd /c start dir 会打开一个新窗口后执行dir指令，原窗口会关闭。
     * cmd /k start dir 会打开一个新窗口后执行dir指令，原窗口不会关闭。
     * @param command
     * @return
     */
    public static List<List<String>> exec(String command){
        String[] commands;
        boolean isWindow = true;
        if(isWindow()){
            commands = new String[]{"cmd", "/c", command};
        }else{
            isWindow = false;
            commands = new String[]{"/bin/sh", "-c", command};
        }
        return exec(commands, isWindow);
    }


    /**
     * 执行命令
     * @param commands
     * @param isWindow
     * @return
     */
    public static List<List<String>> exec(String[] commands, boolean isWindow){
        Runtime r = Runtime.getRuntime();
        BufferedReader stdInput = null;
        BufferedReader stdError = null;
        Process process = null;
        List<List<String>> result = new ArrayList<>();
        List<String> inputList = new ArrayList<>();
        List<String> errorList = new ArrayList<>();
        try {
            process = r.exec(commands);
            if(isWindow){
                stdInput = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
                stdError = new BufferedReader(new InputStreamReader(process.getErrorStream(), "GBK"));
            }else{
                stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
                stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            }
            String line;
            while((line = stdInput.readLine()) != null){
                inputList.add(line);
            }
            String errLine;
            while((errLine = stdError.readLine()) != null){
                errorList.add(errLine);
            }
            //等待命令完成
            process.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(process, stdInput, stdError);
        }
        result.add(inputList);
        result.add(errorList);
        return result;
    }

    /**
     * 判断系统
     * @return
     */
    private static boolean isWindow(){
        String name = System.getProperty("os.name");
        if(name == null){
            return false;
        }
        return name.toLowerCase().contains("windows") || name.toLowerCase().contains("win");
    }

    /**
     * 关闭资源
     * @param process
     * @param input
     * @param error
     */
    private static void close(Process process, Reader input, Reader error){
        if(process != null){
            process.destroy();
        }
        if(input != null){
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(error != null){
            try {
                error.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
